package cn.seaboot.admin.mvc;

import org.springframework.http.HttpStatus;
import org.springframework.lang.Nullable;

import java.io.Serializable;

/**
 * RFC-7807 规范下的问题描述
 * <p>
 * 高版本的 springboot 有配套的 Problem 类，这个版本先自定义实现
 * <p>
 * Encapsulation of an RFC-7807 {@literal Problem} code. While it complies out-of-the-box, it may also be extended to
 * support domain-specific details.
 *
 * @author Mr.css
 * @version 2025-04-08 16:25
 */
public class Problem implements Serializable {

    /**
     * 错误类别 URL，错误的唯一标识符（通常指向文档或规范）。
     */
    @Nullable
    private final String type;
    /**
     * 错误标题，简短的错误摘要（人类可读）。
     */
    @Nullable
    private final String title;

    /**
     * 错误描述，详细的错误描述（可选）。
     */
    @Nullable
    private final String detail;

    /**
     * http 响应状态码，HTTP 状态码（如 400、404、500）。
     */
    @Nullable
    private final HttpStatus status;

    /**
     * 问题发生的 URL 地址，指向错误发生的具体资源（如请求的 URL）。
     */
    @Nullable
    private final String instance;

    /**
     * 扩展字段
     */
    @Nullable
    private final Object extensions;

    public Problem(@Nullable String type, @Nullable HttpStatus status, @Nullable String title, @Nullable String detail, @Nullable String instance, @Nullable Object extensions) {
        this.type = type;
        this.status = status;
        this.title = title;
        this.detail = detail;
        this.instance = instance;
        this.extensions = extensions;
    }

    @Nullable
    public String getInstance() {
        return instance;
    }
    @Nullable
    public String getDetail() {
        return detail;
    }

    @Nullable
    public HttpStatus getStatus() {
        return status;
    }

    @Nullable
    public String getTitle() {
        return title;
    }

    @Nullable
    public String getType() {
        return type;
    }

    @Nullable
    public Object getExtensions() {
        return extensions;
    }

    public static Builder builder() {
        // 这里默认 500，如果需要精准控制，再手动调整
        return new Builder().withStatus(HttpStatus.INTERNAL_SERVER_ERROR);
    }

    public static class Builder {
        @Nullable
        private String type;
        @Nullable
        private String title;
        @Nullable
        private HttpStatus status;
        @Nullable
        private String detail;
        @Nullable
        private String instance;
        @Nullable
        private Object extensions;

        @Nullable
        public String getType() {
            return type;
        }

        public Builder withType(@Nullable String type) {
            this.type = type;
            return this;
        }

        @Nullable
        public String getTitle() {
            return title;
        }

        public Builder withTitle(@Nullable String title) {
            this.title = title;
            return this;
        }

        @Nullable
        public HttpStatus getStatus() {
            return status;
        }

        public Builder withStatus(@Nullable HttpStatus status) {
            this.status = status;
            return this;
        }

        @Nullable
        public String getDetail() {
            return detail;
        }

        public Builder withDetail(@Nullable String detail) {
            this.detail = detail;
            return this;
        }

        @Nullable
        public String getInstance() {
            return instance;
        }

        public Builder withInstance(@Nullable String instance) {
            this.instance = instance;
            return this;
        }

        @Nullable
        public Object getExtensions() {
            return extensions;
        }

        public Builder withExtensions(@Nullable Object extensions) {
            this.extensions = extensions;
            return this;
        }

        public Problem build() {
            return new Problem(type, status, title, detail, instance, extensions);
        }
    }
}
